/**
 *	The NeuroCoSA Toolkit
 *	Copyright (C) 2003-6 Stuart Meikle.
 *
 *	This is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *	Lesser General Public License for more details.
 *
 * @author	Stuart Meikle
 * @version	2006-halloween(mk2)
 * @license	LGPL
 */
package org.stumeikle.NeuroCoSA;

/** Comments:
 *  StuMeikle 20060606. New class to better manage the backpropagation of signals from the synapses
 */

import java.util.*;
import java.lang.*;

public class	SimpleBrain extends Brain
{  
    LinkedList<SimpleBackPropAPI>	iBackPropElements;
    static SimpleBrain			staticReference=null;
    
    public SimpleBrain()
    {
	iBackPropElements = new LinkedList<SimpleBackPropAPI>();
	staticReference = this;
    }
    
    /** Static method, visible to the whole world. stumeikle 20060606
     */
    public	static	void		registerSynapse(SimpleSynapse s)
    {
	SimpleBrain	sb = SimpleBrain.staticReference;

	//do something with sb
	if (sb!=null)
	{
	    sb.iBackPropElements.add( s );
	    System.out.println("SimpleBrain: adding synapse");
	}
    }

    /** Static method, visible to the whole world. stumeikle 20060606
     */
    public	static	void		deregisterSynapse( SimpleSynapse s )
    {
	SimpleBrain	sb = SimpleBrain.staticReference;
	
	if (sb!=null)
	{
	    sb.iBackPropElements.remove( s );   
	}
    }

    public	static	void		registerNeuron( SimpleNeuron n )
    {
	SimpleBrain	sb = SimpleBrain.staticReference;
	if (sb!=null)
	{
	    sb.iBackPropElements.add( n );
	}
    }

    public	static	void		deregisterNeuron( SimpleNeuron n )
    {
	SimpleBrain	sb = SimpleBrain.staticReference;
	
	if (sb!=null)
	{
	    sb.iBackPropElements.remove( n );   
	}	
    }

    /**
     * Update function. Take senses and return actions. Update all the DPUs in order
     * . Overload the base class now and also do the backpropagation
     */
    public  	DataBlock	update(DataBlock ip)
    {
      	DataBlock	r = super.update(ip);
	
	//System.out.println("SimpleBrain: calling back propagate");
	//FUTURE : the number of backprops here should match the max layering of the brain.
	//this current implementation is just a temporary hack
	backPropagate();
	backPropagate();
	backPropagate();
	backPropagate();
	backPropagate();
	backPropagate();

	return r;
    }
    
    public	void		backPropagate()
    {
	//call all the backpropagate methods of all the synapses. 
	//FUTURE: call this N times (calculate N too) to complete all feedback
	ListIterator		i;

	i = iBackPropElements.listIterator(0);
	for(;i.hasNext();)
	{
	    SimpleBackPropAPI	sbpa = (SimpleBackPropAPI)i.next();
	    sbpa.backPropagate();
	}
    }
}

